//
//  ViewController.m
//  EmptyProjectTouchEventAndGesture
//
//  Created by YannisChou on 16/3/21.
//  Copyright © 2016年 Alibaba. All rights reserved.
//
//  在iOS中，如果一个手势A的识别部分是另一个手势B的子部分时，默认情况下A就会先识别，B就无法识别了。
//  要解决这个冲突可以利用- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;方法来完成
//  这个方法可以指定某个手势执行的前提是另一个手势失败才会识别执行,也就是说如果我们指定拖动手势的执行前提为轻扫手势失败就可以了，这样一来当我们手指轻轻
//  滑动时系统会优先考虑轻扫手势，如果最后发现该操作不是轻扫，那么就会执行拖动
//
//  我们知道在iOS的触摸事件中，事件触发是根据响应者链进行的，上层触摸事件执行后就不再向下传播.
//  默认情况下手势也是类似的，先识别的手势会阻断手势识别操作继续传播。那么如何让两个有层次关系并且都添加了手势的控件都能正确识别手势呢
//  答案就是利用代理的-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
//  shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法。
//  这个代理方法默认返回NO，会阻断继续向下识别手势，如果返回YES则可以继续向下传播识别。
//
//  演示了当在图片上长按时同时可以识别控制器视图的长按手势（注意其中我们还控制了只有在UIImageView中操作的手势才能向下传递，如果不控制则所有控件都可以
//  向下传递）

#import "KCPhotoViewController.h"
#define kImageCount 3

@interface KCPhotoViewController ()<UIGestureRecognizerDelegate>{
    UIImageView *_imageView; // 图片展示控件
    int _currentIndex; // 当前图片索引
}

@end

@implementation KCPhotoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self initLayout];
    
    [self addGesture];
}

#pragma mark 布局
-(void)initLayout{
    // 添加图片展示控件
    CGSize screenSize = [[UIScreen mainScreen] bounds].size;
    CGFloat topPadding = 20;
    CGFloat y = 22+44+topPadding,height = screenSize.height-y-topPadding;
    
    CGRect imageFrame = CGRectMake(0, y, screenSize.width, height);
    _imageView = [[UIImageView alloc] initWithFrame:imageFrame];
    _imageView.contentMode = UIViewContentModeScaleToFill; // 设置内容模式为缩放填充
    _imageView.userInteractionEnabled = YES; // 这里必须设置为YES，否则无法接收手势操作
    [self.view addSubview:_imageView];
    
    // 添加默认图片
    UIImage *image = [UIImage imageNamed:@"Image"];
    _imageView.image = image;
    [self showPhotoName];
}

#pragma mark 添加手势
-(void)addGesture{
    // 添加点按手势
    // 创建手势对象
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImage:)];
    // 设置手势属性
    tapGesture.numberOfTapsRequired = 1; //设置点按次数，默认为1，注意在iOS中很少用双击操作
    tapGesture.numberOfTouchesRequired = 1; //点按的手指数
    //添加手势到对象(注意，这里添加到了控制器视图中，而不是图片上，否则点击空白无法隐藏导航栏)
    [self.view addGestureRecognizer:tapGesture];
    
    // 添加长按手势
    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressImage:)];
    longPressGesture.minimumPressDuration = 0.5; //设置长按时间，默认0.5秒，一般这个值不要修改
    //注意由于我们要做长按提示删除操作，因此这个手势不再添加到控制器视图上而是添加到了图片上
    [_imageView addGestureRecognizer:longPressGesture];
    
    // 添加捏合手势
    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchImage:)];
    [self.view addGestureRecognizer:pinchGesture];
    
    // 添加旋转手势
    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateImage:)];
    [self.view addGestureRecognizer:rotationGesture];
    
    // 添加拖动手势
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panImage:)];
    [_imageView addGestureRecognizer:panGesture];
    
    // 添加轻扫手势
    // 注意一个轻扫手势只能控制一个方向，默认向右，通过direction进行方向控制
    UISwipeGestureRecognizer *swipeGestureToRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeImage:)];
    // swipeGestureToRight.direction = UISwipeGestureRecognizerDirectionRight;// 默认向右扫
    [self.view addGestureRecognizer:swipeGestureToRight];
    
    UISwipeGestureRecognizer *swipeGestureToLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeImage:)];
    swipeGestureToLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipeGestureToLeft];
    
    // 解决在图片上滑动时拖动手势和轻扫手势的冲突
    [panGesture requireGestureRecognizerToFail:swipeGestureToRight];
    [panGesture requireGestureRecognizerToFail:swipeGestureToLeft];
    // 解决拖动和长按手势之间的冲突
    [longPressGesture requireGestureRecognizerToFail:panGesture];
    
    // 演示不同视图的手势同时执行
    // 在上面_imageView已经添加了长按手势，这里给视图控制器的视图也加上长按手势让两者都执行
    self.view.tag = 100;
    _imageView.tag = 200;
    UILongPressGestureRecognizer *viewLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressView:)];
    viewLongPressGesture.delegate = self;
    [self.view addGestureRecognizer:viewLongPressGesture];
}

#pragma mark 显示图片名称
-(void)showPhotoName{
    NSString *title = [NSString stringWithFormat:@"%i.jpg",_currentIndex];
    NSLog(@"%@",title);
    [self setTitle:title];
}

#pragma mark 下一张图片
-(void)nextImage{
    int index = (_currentIndex+kImageCount+1)%kImageCount;
    NSString *imageName = [NSString stringWithFormat:@"%i.jpg",index];
    _imageView.image = [UIImage imageNamed:imageName];
    _currentIndex = index;
    [self showPhotoName];
}

#pragma mark 上一张图片
-(void)lastImage{
    int index = (_currentIndex+kImageCount-1)%kImageCount;
    NSString *imageName = [NSString stringWithFormat:@"%i.jpg",index];
    _imageView.image = [UIImage imageNamed:imageName];
    _currentIndex = index;
    [self showPhotoName];
}

#pragma mark - 手势操作
#pragma mark 点按隐藏或显示导航栏
-(void)tapImage:(UITapGestureRecognizer *)gesture{
    NSLog(@"tap:%ld",gesture.state);
    BOOL hidden = !self.navigationController.navigationBarHidden;
    [self.navigationController setNavigationBarHidden:hidden animated:YES];
}

#pragma mark 长按提示是否删除
-(void)longPressImage:(UILongPressGestureRecognizer *)gesture{
    NSLog(@"longpress:%ld",gesture.state);
    //注意其实在手势里面有一个view属性可以获取点按的视图
    //UIImageView *imageView=(UIImageView *)gesture.view;
    
    //由于连续手势此方法会调用多次，所以需要判断其手势状态
    if (gesture.state == UIGestureRecognizerStateBegan) {
        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"System Info" delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete the photo" otherButtonTitles:nil, nil];
        [actionSheet showInView:self.view];
    }
}

#pragma mark 捏合时缩放图片
-(void)pinchImage:(UIPinchGestureRecognizer *)gesture{
    NSLog(@"pinch:%ld",gesture.state);
    if (gesture.state == UIGestureRecognizerStateChanged) {
        // 捏合手势中scale属性记录的缩放比例
        _imageView.transform = CGAffineTransformMakeScale(gesture.scale, gesture.scale);
    }else if (gesture.state == UIGestureRecognizerStateEnded){ // //结束后恢复
        [UIView animateWithDuration:5 animations:^{
            _imageView.transform = CGAffineTransformIdentity; //取消一切形变
        }];
    }
}

#pragma mark 旋转图片
-(void)rotateImage:(UIRotationGestureRecognizer *)gesture{
    NSLog(@"rotate:%ld",gesture.state);
    if (gesture.state == UIGestureRecognizerStateChanged) {
        // 旋转手势中rotation属性记录了旋转弧度
        _imageView.transform = CGAffineTransformMakeRotation(gesture.rotation);
    }else if (gesture.state == UIGestureRecognizerStateEnded){
        [UIView animateWithDuration:0.8 animations:^{
            _imageView.transform = CGAffineTransformIdentity;// 取消形变
        }];
    }
}

#pragma mark 拖动图片
-(void)panImage:(UIPanGestureRecognizer *)gesture{
    if (gesture.state == UIGestureRecognizerStateChanged) {
        CGPoint translation = [gesture translationInView:self.view];//利用拖动手势的translationInView:方法取得在相对指定视图（这里是控制器根视图）的移动
        _imageView.transform = CGAffineTransformMakeTranslation(translation.x, translation.y);
    }else if (gesture.state == UIGestureRecognizerStateEnded){
        [UIView animateWithDuration:0.5 animations:^{
            _imageView.transform = CGAffineTransformIdentity;
        }];
    }
}

#pragma mark 轻扫则查看下一张或上一张
//注意虽然轻扫手势是连续手势，但是只有在识别结束才会触发，不用判断状态
-(void)swipeImage:(UISwipeGestureRecognizer *)gesture{
    NSLog(@"swip:%ld",gesture.state);
    //direction记录的轻扫的方向
    if (gesture.direction == UISwipeGestureRecognizerDirectionRight) {
        [self nextImage];
    }else if (gesture.direction == UISwipeGestureRecognizerDirectionLeft){
        [self lastImage];
    }
}

#pragma mark 控制器视图的长按手势
-(void)longPressView:(UILongPressGestureRecognizer *)gesture{
    NSLog(@"view long press");
}

#pragma mark 手势代理方法
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    NSLog(@"%li,%li",gestureRecognizer.view.tag,otherGestureRecognizer.view.tag);
    // 注意，这里控制只有在UIImageView中才能向下传播，其他情况不允许
    if ([otherGestureRecognizer.view isKindOfClass:[UIImageView class]]) {
        return YES;
    }
    return NO;
}

#pragma mark - 触摸事件
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"touch begin...");
}

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"touch end.");
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
